package org.qdog.pk.pkscrape.dao;

import org.qdog.pk.pkscrape.entity.Entity;
import org.qdog.pk.pkscrape.entity.EntityType;
import org.qdog.pk.pkscrape.entity.PersistentObject;
import org.qdog.pk.pkscrape.entity.Relationship;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.Collection;
import java.util.Date;

/**
 * @since 08/2011
 */
@Repository
public class Dao {

  @PersistenceContext(name = "pkscrape")
  private EntityManager em;

  public <T extends PersistentObject> T loadById(String id) {
    //noinspection unchecked
    return (T) em.find(Entity.class, id);
  }

  public <T extends PersistentObject> T persist(T newEntity) {
    em.persist(newEntity);
    return newEntity;
  }

  @SuppressWarnings({"unchecked"})
  public Collection<Relationship> loadActiveRelationshipsForEntity(Entity entity) {
    Query query = em.createQuery("select r from Relationship r where (r.sourceEntityId = :sourceEntityId or r.targetEntityId = :targetEntityId) and r.end is null")
          .setParameter("sourceEntityId", entity.getId())
          .setParameter("targetEntityId", entity.getId());
    return query.getResultList();
  }

  public Collection<Entity> loadNewEntities() {
    Query query = em.createQuery("select e from Entity e where e.lastUpdate is null");
    return query.getResultList();
  }

  public Collection<Entity> loadNewEntities(EntityType type) {
    String className = type.getEntityClass().getSimpleName();
    Query query = em.createQuery("select e from " + className + " e where e.lastUpdate is null");
    return query.getResultList();
  }

  public Collection<Entity> loadStaleEntities(EntityType type, Date lastUpdate) {
    String className = type.getEntityClass().getSimpleName();
    Query query = em.createQuery("select e from " + className + " e where e.lastUpdate < :lastUpdate").setParameter("lastUpdate", lastUpdate);
    return query.getResultList();
  }

  public void flush() {
    em.flush();
  }
}
